home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / comm / mail / YamNet.lha / FSCode.lha / Src / FSCode.c < prev    next >
C/C++ Source or Header  |  1995-11-13  |  6KB  |  253 lines

  1. /*
  2. ** $VER: FSCode.c (22.5.95) by Flavio Stanchina
  3. ** Loc. Montevaccino, 39
  4. ** 38040 Trento (Italy)
  5. ** 2:333/408.9@fidonet.org
  6. */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/alerts.h>
  10. #include <exec/memory.h>
  11. #include <dos/dos.h>
  12. #include <dos/dosasl.h>
  13. #include <dos/dosextens.h>
  14. #include <dos/rdargs.h>
  15. #include <dos/stdio.h>
  16.  
  17. #include <clib/exec_protos.h>
  18. #include <clib/utility_protos.h>
  19. #include <clib/dos_protos.h>
  20.  
  21. #include <ctype.h>
  22. #include <string.h>
  23.  
  24. #if defined(__SASC)
  25. #define _USEOLDEXEC_
  26. #include <proto/exec.h>
  27. #include <proto/utility.h>
  28. #include <proto/dos.h>
  29. #endif
  30.  
  31. #include "FSCode.h"
  32. #include "FSCode_rev.h"
  33. #include "CRC32.h"
  34.  
  35. /***** Strings *****/
  36. TEXT StartFmt[] = "!start %s\n";
  37. TEXT MultiFmt[] = "!mstrt %ld/%ld %s\n";
  38. TEXT   EndFmt[] = "!end %ld %lx\n\n";
  39. TEXT  NameFmt[] = "%s%ld";
  40.  
  41. TEXT Template[] = "FILE/A,TO,E=ENCODE/S,M=MULTI/S,L=LINES/N" VERSTAG " by Flavio Stanchina";
  42.  
  43. LONG FSCode(VOID)
  44. {
  45.     struct RDArgs  *rda;
  46.     struct FSData  *fsd;
  47.     struct Process *pr;
  48.     ULONG tmp;
  49.  
  50.     if (fsd = AllocMem(sizeof(struct FSData), MEMF_CLEAR))
  51.     {
  52.         /* Open libraries (and make sure we're on OS 2.04 or greater) */
  53.         if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) == NULL)
  54.         {
  55.             Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
  56.             return RETURN_FAIL + 0;
  57.         }
  58.  
  59.         if ((UtilityBase = OpenLibrary("utility.library", 37)) == NULL)
  60.         {
  61.             Alert(AT_Recovery | AG_OpenLib | AO_UtilityLib);
  62.             return RETURN_FAIL + 1;
  63.         }
  64.  
  65.         pr = (struct Process *)FindTask(NULL);
  66.         if (pr->pr_CES == 0)
  67.         {
  68.             struct CommandLineInterface *cli = Cli();
  69.  
  70.             if (cli && cli->cli_StandardOutput)
  71.                 fsd->StdErr = cli->cli_StandardOutput;
  72.             else fsd->StdErr = pr->pr_COS;
  73.         }
  74.         else fsd->StdErr = pr->pr_CES;
  75.  
  76.         if (rda = ReadArgs(Template, (LONG *)fsd, NULL))
  77.         {
  78.             /* Set up CRC table */
  79.             CRC32_init();
  80.  
  81.             /* Encode or decode? */
  82.             if (fsd->Encode)
  83.             {
  84.                 if (fsd->In = Open(fsd->File, MODE_OLDFILE))
  85.                 {
  86.                     if ((fsd->RealSize = FileSizeFH(fsd, fsd->In)) > 0)
  87.                     {
  88.                         if (fsd->Multi)
  89.                         {
  90.                             fsd->Lines = 100;
  91.  
  92.                             if (fsd->pLines)
  93.                             {
  94.                                 if (*fsd->pLines < 2)
  95.                                     FPuts(fsd->StdErr, "too few LINES -- using default value\n");
  96.                                 else fsd->Lines = *fsd->pLines;
  97.                             }
  98.  
  99.                             // fsd->Parts = (((fsd->RealSize - 1) / 60) + fsd->Lines - 1) / fsd->Lines;
  100.                             tmp = UDivMod32(fsd->RealSize - 1, 60);
  101.                             fsd->Parts = UDivMod32(tmp + fsd->Lines - 1, fsd->Lines);
  102.                             if (fsd->Parts <= 1) fsd->Multi = 0; // easier
  103.                         }
  104.  
  105.                         switch (Encode(fsd))
  106.                         {
  107.                             case -3:
  108.                                 MyPrintFault(fsd, ERROR_BREAK, NULL);
  109.                                 break;
  110.                         }
  111.                     }
  112.                     else FPrintf(fsd->StdErr, "file \"%s\" is empty\n", fsd->File);
  113.  
  114.                     MyClose(fsd, fsd->In);
  115.                 }
  116.                 else MyPrintFault(fsd, IoErr(), fsd->File);
  117.             }
  118.             else 
  119.             {
  120.                 if (fsd->pLines)
  121.                     FPuts(fsd->StdErr, "LINES is meaningless in decode mode -- ignored\n");
  122.  
  123.                 if (OpenPart(fsd))
  124.                 {
  125.                     switch(Decode(fsd))
  126.                     {
  127.                         case '!':
  128.                             FPuts(fsd->StdErr, "illegal '!' -- file corrupt\n");
  129.                             break;
  130.                         case -1:
  131.                             FPuts(fsd->StdErr, "unexpected EOF\n");
  132.                             break;
  133.                         case -2:
  134.                             MyPrintFault(fsd, IoErr(), fsd->To);
  135.                             break;
  136.                         case -3:
  137.                             MyPrintFault(fsd, ERROR_BREAK, NULL);
  138.                             break;
  139.                     }
  140.  
  141.                     ClosePart(fsd, 0); // flush the output file
  142.                     // NOTE: This is meaningful only in case of errors, 'cause if
  143.                     // all went ok the file has already been closed when the !end
  144.                     // line has been encountered.
  145.                 }
  146.  
  147.                 /* Did we decode anything at all? */
  148.                 if (fsd->NumFound == 0)
  149.                     FPuts(fsd->StdErr, "no start line\n");
  150.  
  151.                 /* Make sure files are closed. Should hit these only in case of errors. */
  152.                 if (fsd->In ) MyClose(fsd, fsd->In );
  153.                 if (fsd->Out) MyClose(fsd, fsd->Out);
  154.             }
  155.  
  156. free:
  157.             FreeArgs(rda);
  158.         }
  159.         else MyPrintFault(fsd, IoErr(), NULL);
  160.  
  161.         CloseLibrary((struct Library *)DOSBase);
  162.         CloseLibrary((struct Library *)UtilityBase);
  163.  
  164.         FreeMem(fsd, sizeof(struct FSData));
  165.     }
  166.     else Alert(AT_Recovery | AG_NoMemory);
  167.  
  168.     return RETURN_OK;
  169. }
  170.  
  171. /***** Restituisce la lunghezza di un file già aperto *****/
  172. LONG FileSizeFH(struct FSData *fsd, BPTR fh)
  173. {
  174.     struct FileInfoBlock *fib;
  175.     LONG size = -1;
  176.  
  177.     if (fib = AllocDosObject(DOS_FIB, NULL))
  178.     {
  179.         if (ExamineFH(fh, fib))
  180.             size = fib->fib_Size;
  181.         FreeDosObject(DOS_FIB, fib);
  182.     }
  183.  
  184.     return size;
  185. }
  186.  
  187. /***** Print fault on given file *****/
  188. VOID MyPrintFault(struct FSData *fsd, LONG code, STRPTR header)
  189. {
  190.     static TEXT buffer[256];
  191.  
  192.     Fault(code, header, buffer, 256);
  193.     FPrintf(fsd->StdErr, "\a%s\n", buffer);
  194.     Flush(fsd->StdErr);
  195. }
  196.  
  197. /***** Close file and check for errors *****/
  198. BOOL MyClose(struct FSData *fsd, BPTR fh)
  199. {
  200.     BOOL rc;
  201.  
  202.     if ((rc = Close(fh)) == 0)
  203.         MyPrintFault(fsd, IoErr(), "error closing file");
  204.  
  205.     return rc;
  206. }
  207.  
  208. /***** Get a decimal number from a string *****/
  209. LONG GetDec(STRPTR *line)
  210. {
  211.     LONG l = 0;
  212.  
  213.     while (!isdigit(*(*line))) (*line)++;
  214.     while ( isdigit(*(*line))) l = (l * 10) + (*(*line)++ - '0');
  215.  
  216.     return l;
  217. }
  218.  
  219. /***** Get a hexadecimal number from a string *****/
  220. static LONG h2l(LONG c)
  221. {
  222.     if (c >= 'a') return c - 'a' + 10; // 'f' > 'F'
  223.     if (c >= 'A') return c - 'A' + 10; // 'F' < 'f'
  224.     return c - '0';
  225. }
  226.  
  227. LONG GetHex(STRPTR *line)
  228. {
  229.     LONG l = 0;
  230.  
  231.     while (!isxdigit(*(*line))) (*line)++;
  232.     while ( isxdigit(*(*line))) l = (l * 16) + h2l(*(*line)++);
  233.  
  234.     return l;
  235. }
  236.  
  237. /***** Remove leading spaces and trailing control characters *****/
  238. VOID TrimLine(STRPTR *line)
  239. {
  240.     register i;
  241.  
  242.     while (isspace(*(*line))) (*line)++;
  243.     for (i = 0; (*line)[i] & 0x60; i++);
  244.     (*line)[i] = '\0';
  245. }
  246.  
  247. VOID SPrintf(STRPTR buf, STRPTR fmt, ...)
  248. {
  249.     RawDoFmt(fmt, (APTR)(&fmt + 1), stuff, buf);
  250. }
  251.  
  252. /***** EOF *****/
  253.